﻿using System.Net;
using System.Net.Sockets;
using System.Text;

namespace ClassLibrary_fqy_NET.SocketHelper
{
    public class TcpClientAsync
    {
        private Socket? worksocket;
        /// <summary>
        /// 连接的服务器Socket
        /// </summary>
        public Socket? SeverSocket
        {
            get { return worksocket; }
            private set { worksocket = value; }
        }
        /// <summary>
        /// 数据接收委托
        /// </summary>
        /// <param name="buff"></param>
        public delegate void OnReceiveData(byte[] buff);
        /// <summary>
        /// 数据接收事件
        /// </summary>
        public event OnReceiveData? ReceiveSeverData;

        /// <summary>
        /// 初始化
        /// </summary>
        public TcpClientAsync()
        {

        }
        /// <summary>
        /// 异步连接服务器
        /// </summary>
        /// <param name="iP">服务器ip</param>
        /// <param name="port">服务器port</param>
        public async Task<bool> ConnectSever(IPAddress iP, int port)
        {
            try
            {
                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                await socket.ConnectAsync(iP, port);
                worksocket = socket;
                await ReceiveDataAsync();
                return true;
            }
            catch
            {
                return false;
            }

        }
        /// <summary>
        /// 异步断开连接服务器
        /// </summary>
        /// <returns></returns>
        public async Task DisconnectSever()
        {
            if (worksocket != null)
            {
                await worksocket.DisconnectAsync(true);
            }
        }
        /// <summary>
        /// 数据异步接收
        /// </summary>
        private async Task ReceiveDataAsync()
        {
            var buffer = new ArraySegment<byte>();
            var datalength = await worksocket!.ReceiveAsync(buffer, SocketFlags.None);
            if (datalength > 0)
            {
                var data = buffer.ToArray();
                if (ReceiveSeverData != null)
                {
                    ReceiveSeverData.Invoke(data);
                }
                await ReceiveDataAsync();
            }
        }
        /// <summary>
        /// 异步发送数据
        /// </summary>
        /// <param name="data">要发送的数据</param>
        /// <returns></returns>
        public async Task<int> SendDataAsync(byte[] data, SocketFlags socketFlags = SocketFlags.None)
        {
            var result = 0;
            if (worksocket != null)
            {
                try
                {
                    var buffer = new ArraySegment<byte>(data);
                    result = await worksocket.SendAsync(buffer, socketFlags);
                }
                catch
                {
                    result = -1;
                    worksocket = null;
                }

                return result;
            }
            else
            {
                return result;
            }
        }
        /// <summary>
        /// 异步发送数据
        /// </summary>
        /// <param name="data">要发送的数据</param>
        /// <param name="offset">范围中第一个元素的从零开始的索引</param>
        /// <param name="count">范围内的元素数量</param>
        /// <returns></returns>
        public async Task<int> SendDataAsync(byte[] data, int offset, int count, SocketFlags socketFlags = SocketFlags.None)
        {
            var result = 0;
            if (worksocket != null)
            {
                try
                {
                    var buffer = new ArraySegment<byte>(data, offset, count);
                    result = await worksocket.SendAsync(buffer, socketFlags);
                }
                catch
                {
                    result = -1;
                    worksocket = null;
                }

                return result;
            }
            else
            {
                return result;
            }
        }
        /// <summary>
        /// 异步发送数据
        /// </summary>
        /// <param name="strdata">要发送的字符串</param>
        /// <returns></returns>
        public async Task<int> SendDataAsync(string strData, SocketFlags socketFlags = SocketFlags.None)
        {
            var data = Encoding.ASCII.GetBytes(strData);
            var result = 0;
            if (worksocket != null)
            {
                try
                {
                    var buffer = new ArraySegment<byte>(data);
                    result = await worksocket.SendAsync(buffer, socketFlags);
                }
                catch
                {
                    result = -1;
                    worksocket = null;
                }

                return result;
            }
            else
            {
                return result;
            }
        }


    }
}
